/**
 * Copyright (c) 2012, Brent Mucci
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice, 
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice, 
 *    this list of conditions and the following disclaimer in the documentation 
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 **/

#ifndef _MCL_SLICE_HPP
#define _MCL_SLICE_HPP

#include "mcl_bitstream_buffer.hpp"
#include <vector>

namespace mcl
{

	/**
	Separate these classes into different files.

	*/
class SliceHeader
{
public:
	SliceHeader(BitstreamBuffer &bitstream);
	unsigned int m_first_mb_in_slice;
	unsigned int m_slice_type;
	unsigned int m_pic_parameter_set_id;
	unsigned char m_colour_plane_id;
	unsigned int m_frame_num;
	unsigned char m_field_pic_flag;
	unsigned char m_bottom_field_flag;
	unsigned int m_idr_pic_id;
	unsigned int m_pic_order_cnt_lsb;
	signed int m_delta_pic_order_cnt_bottom;
	std::vector<signed int> m_delta_pic_order_cnt;
	unsigned int m_redundant_pic_cnt;
	unsigned char m_direct_spatial_mv_pred_flag;
	unsigned char m_num_ref_idx_active_override_flag;
	unsigned int m_num_ref_idx_l0_active_minus1;
	unsigned int m_num_ref_idx_l1_active_minus1;
	unsigned int m_cabac_init_idc;
	signed int m_slice_qp_delta;
	unsigned char m_sp_for_switch_flag;
	signed int m_slice_qs_delta;
	unsigned int m_disable_deblocking_filter_idc;
	signed int m_slice_alpha_c0_offset_div2;
	signed int m_slice_beta_offset_div2;
	unsigned int m_slice_group_change_cycle;
	unsigned char m_ref_pic_list_modification_flag_l0;
	unsigned int m_modification_of_pic_nums_idc;
	unsigned int m_abs_diff_pic_num_minus1;
	unsigned int m_long_term_pic_num;
	unsigned char m_ref_pic_list_modification_flag_l1;
	unsigned int m_modification_of_pic_nums_idc;
	unsigned int m_abs_diff_pic_num_minus1;
	unsigned int m_long_term_pic_num;
};

class RefPicListModification
{
public:
	RefPicListModification(BitstreamBuffer &bitstream);
	unsigned char m_ref_pic_list_modification_flag_l0;
	unsigned int m_modification_of_pic_nums_idc;
	unsigned int m_abs_diff_pic_num_minus1;
	unsigned int m_long_term_pic_num;
	unsigned char m_ref_pic_list_modification_flag_l1;
	unsigned int m_modification_of_pic_nums_idc;
	unsigned int m_abs_diff_pic_num_minus1;
	unsigned int m_long_term_pic_num;
};
//Page 74
class PredictWeightTable
{
public:
	unsigned int m_luma_log2_weight_denom;
	unsigned int m_chroma_log2_weight_denom;
	unsigned char m_luma_weight_l0_flag;
	std::vector<signed int> m_luma_weight_l0;
	std::vector<signed int> m_luma_offset_l0;
	unsigned char m_chroma_weight_l0_flag;
	std::vector<signed int> m_chroma_weight_l0;
	std::vector<signed int> m_chroma_offset_l0;
	unsigned char m_luma_weight_l1_flag;
	std::vector<signed int> m_luma_weight_l1;
	std::vector<signed int> m_luma_offset_l1;
	unsigned char m_chroma_weight_l1_flag;
	std::vector<signed int> m_chroma_weight_l1;
	std::vector<signed int> m_chroma_offset_l1;
};
class DecodeRefPicMarking
{
public:
	unsigned char m_no_output_of_prior_pics_flag;
	unsigned char m_long_term_reference_flag;
	unsigned char m_adaptive_ref_pic_marking_mode_flag;
	unsigned int m_memory_management_control_operation;
	unsigned int m_difference_of_pic_nums_minus1;
	unsigned int m_long_term_pic_num;
	unsigned int m_long_term_frame_idx;
	unsigned int m_max_long_term_frame_idx_plus1;
};
class SliceData
{
public:
	unsigned char m_cabac_alignment_one_bit;
	unsigned int m_mb_skip_run;
	unsigned int m_mb_skip_flag;
	unsigned int m_mb_field_decoding_flag;
	unsigned int m_end_of_slice_flag;
};
class MacroblockLayer
{
public:
	unsigned int m_mb_type;
	unsigned char m_pcm_alignment_zero_bit;
	std::vector<unsigned int> m_pcm_sample_luma;
	std::vector<unsigned int> m_pcm_sample_chroma;
	unsigned int m_transform_size_8x8_flag;
	unsigned int m_coded_block_pattern;
	unsigned int m_transform_size_8x8_flag;
	signed int m_mb_qp_delta;
};
class MBPrediction
{
public:
	std::vector<unsigned int> m_prev_intra4x4_pred_mode_flag;
	std::vector<unsigned int> m_rem_intra4x4_pred_mode;
	std::vector<unsigned int> m_prev_intra8x8_pred_mode_flag;
	std::vector<unsigned int> m_rem_intra8x8_pred_mode;
	unsigned int m_intra_chroma_pred_mode;
	std::vector<signed int> m_ref_idx_l0;
	std::vector<signed int> m_ref_idx_l1;
	std::vector<signed int> m_mvd_l0;
	std::vector<signed int> m_mvd_l1;
};
class SubMBPrediction
{
public:
	std::vector<unsigned int> m_sub_mb_type;
	std::vector<signed int> m_ref_idx_l0;
	std::vector<signed int> m_ref_idx_l1;
	std::vector<signed int> m_mvd_l0;
	std::vector<signed int> m_mvd_l1;
};
class ResidualBlockCavlc
{
public:
	signed int m_coeff_token;
	unsigned char m_trailing_ones_sign_flag;
	signed int m_level_prefix;
	unsigned int m_level_suffix;
	signed int m_run_before;
};
class ResidualBlockCabac
{
public:
	signed int m_coded_block_flag;
	std::vector<signed int> m_significant_coeff_flag;
	std::vector<signed int> m_last_significant_coeff_flag;
	std::vector<signed int> m_coeff_abs_level_minus1;
	std::vector<signed int> m_coeff_sign_flag;
	std::vector<signed int> m_coeff_abs_level_minus1;
	std::vector<signed int> m_coeff_sign_flag;
};
};

#endif